package com.skyinno.mrms.common.controller;

import java.io.DataOutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.sql.Timestamp;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import org.springframework.web.util.WebUtils;

import com.skyinno.mrms.common.model.FileModel;
import com.skyinno.mrms.common.model.JsonModel;
import com.skyinno.mrms.common.service.BaseService;
import com.skyinno.mrms.utils.Constants;
import com.skyinno.mrms.utils.FrameException;
import com.skyinno.mrms.utils.Message;
import com.skyinno.mrms.utils.TimestampEditor;

public class BaseController implements ApplicationContextAware {
    protected Logger logger = Logger.getLogger(this.getClass());

    protected ApplicationContext ac;

    @Autowired
    protected Message message;

    protected ObjectMapper om = new ObjectMapper();

    private BaseService service;

    public void setApplicationContext(ApplicationContext arg0)
            throws BeansException {
        this.ac = arg0;
    }

    @ExceptionHandler
    public ModelAndView error(HttpServletRequest request, Exception e)
            throws Exception {
        logger.error(e.getMessage(), e);
        e.printStackTrace();
        return new ModelAndView(Constants.ERROR_VIEW_NAME,
                Constants.PAGE_DATE_ATTRIBUTE, new JsonModel(
                        e instanceof FrameException ? e.getMessage()
                                : this.message.getMessage("server.error", this
                                        .getLocale(request))));
    }

    protected void setResponse(ModelMap modelMap, boolean success, Object root) {
        modelMap.clear();
        modelMap.addAttribute(new JsonModel(success, root));
    }

    protected void setResponse(ModelMap modelMap, boolean success) {
        this.setResponse(modelMap, success, null);
    }

    protected Locale getLocale(HttpServletRequest request) {
        Locale locale = (Locale) WebUtils.getSessionAttribute(request,
                SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME);
        return locale == null ? Locale.SIMPLIFIED_CHINESE : locale;
    }

    @InitBinder
    protected void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(Timestamp.class, new TimestampEditor());
    }

    @RequestMapping("/fileSizeError.plain")
    public JsonModel fileSizeError(HttpServletRequest request) {
        return new JsonModel(this.message.getMessage("file.size.error", this
                .getLocale(request)));
    }

    protected String getLoginUser(HttpServletRequest request) {
        return (String) WebUtils.getSessionAttribute(request,
                Constants.LOGIN_USER);
    }

    @RequestMapping("/list.html")
    public void list(HttpServletRequest request, ModelMap modelMap)
            throws Exception {
    }

    protected String getPathPrefix() {
        if (this.getClass().getAnnotation(Controller.class) != null) {
            RequestMapping rm = this.getClass().getAnnotation(
                    RequestMapping.class);
            if (rm != null) {
                return rm.value()[0];
            }
        }
        return "";
    }

    protected Map<String, Object> setGridData(int total, Collection<?> rows) {
        Map<String, Object> data = new HashMap<String, Object>();
        data.put("total", total);
        data.put("rows", rows);
        return data;
    }

    /**
     * 获取request中非空的参数
     * 
     * @param params
     * @param paramKeys
     * @param request
     */
    public static void getNotEmptyParams(Map<String, String> params,
            List<String> paramKeys, HttpServletRequest request) {
        if (paramKeys != null && paramKeys.size() > 0) {
            for (String key : paramKeys) {
                String param = request.getParameter(key);
                if (StringUtils.isNotEmpty(param)) {
                    params.put(key, param);
                }
            }
        }
    }

    protected String getEditorLanguage(HttpServletRequest request) {
        return Locale.ENGLISH.equals(this.getLocale(request)) ? "en" : "zh-cn";
    }

    protected String getUrl(HttpServletRequest request, String uri) {
        return new StringBuilder().append(request.getScheme()).append("://")
                .append(request.getServerName()).append(
                        StringUtils.isBlank(uri) ? request.getRequestURI()
                                + (StringUtils
                                        .isEmpty(request.getQueryString()) ? ""
                                        : "?"
                                                + request.getQueryString())
                                : request.getContextPath()
                                        + (uri.startsWith("/") ? "" : "/")
                                        + uri).toString();
    }

    protected <T> T request(String url, String params, Class<T> clz,
            Locale locale) throws Exception {
        HttpURLConnection connection = (HttpURLConnection) new URL(url)
                .openConnection();
        connection.setDoInput(true);
        connection.setDoOutput(true);
        connection.setUseCaches(false);
        connection.setConnectTimeout(60000);
        connection.setRequestMethod("POST");
        if (StringUtils.isNotBlank(params)) {
            DataOutputStream dos = new DataOutputStream(connection
                    .getOutputStream());
            dos.write(params.getBytes(Constants.ENCODE));
            dos.flush();
        }
        if (connection.getResponseCode() == 200) {
            return new ObjectMapper().readValue(StringUtils.join(IOUtils
                    .readLines(connection.getInputStream(), Constants.ENCODE),
                    ""), clz);
        }
        throw new FrameException(this.message.getMessage("request.error",
                locale));
    }

    @RequestMapping("/file.dl")
    public FileModel file(String id) {
        return service.fileEx(id);
    }
    
    @RequestMapping("/test/test")
    public String test() {
        return "test";
    }
}
